﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

using alib;
using alib.Enumerable;
using alib.Collections;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public sealed class GenRuleSkol : identity_base, IActiveRule, IProximalContext<CoverageMap>
	{
		public GenRuleSkol(Rule r, SkolemizationResult skr)
			: base(skr.w.input)
		{
			var tfs = skr.tfs;

			this.r = r;
			this.w = skr.w;
			this.rgts = tfs[tfs.im.RuleArgsPath].ListSlots;

			if (this.rgts == null)
				throw new Exception("Could not find daughters in rule TFS.");
		}

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		readonly Rule r;

		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		public TfsSlot[] rgts;

		//////////////////////////////////////////////////////////////////////
		/// IProximalContext(CoverageMap)
		//////////////////////////////////////////////////////////////////////
		[DebuggerBrowsable(DebuggerBrowsableState.Never)]
		CoverageMap w;
		int IProximalContext<CoverageMap>.CoverageCount { get { return w.c_covered; } }
		bool IProximalContext<CoverageMap>.CombineWith(CoverageMap other, out CoverageMap result) { return w.CombineWith(other, out result); }
		bool IProximalContext<CoverageMap>.CanCombineWith(CoverageMap other) { return w.CanCombineWith(other); }

		//////////////////////////////////////////////////////////////////////
		/// IActiveRule
		//////////////////////////////////////////////////////////////////////
		public Rule BaseRule { get { return r; } }

		public TfsSlot[] DaughterNodes { get { return rgts; } }


		public override String ToString()
		{
			return String.Format("{0,20} {1}", r.Name, w.ToString());
		}
	};


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public class vacuous_lexent : GenControl._lexent_chartobj, IChartObj<CoverageMap>
	{
		public vacuous_lexent(IRtParent parent, LexicalEntry le, CoverageMap w)
			: base(parent, le, le.Expanded, w)
		{
		}
	};


	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public class skol_lexent : GenControl._lexent_chartobj, IChartObj<CoverageMap>, ILexicalDerivation
	{
		public skol_lexent(IRtParent parent, LexicalEntry le, SkolemizationResult skr)
			: base(parent, le, skr.tfs, skr.w)
		{
		}
	};


#if IN_GENERATION_UNARY_RULES_CAN_CHANGE_CONTEXT
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public class atfs_unary : _atfs_unary<GenControl, GenChart, IGenChartObj>
	{
		public _atfs_unary(GenControl ctrl, Rule rule, Tfs tfs, IChartObj o, ChartCoverageContext ccc)
			: base(ctrl, rule, tfs, o)
		{
		}
	};
#endif

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public class gxo_nary : GenControl._atfs_nary, IChartObj<CoverageMap>
	{
		public gxo_nary(IUnificationController parent, Rule rule, ArrayTfs tfs, IReadOnlyList<IChartObj> rgo, CoverageMap w, StartSymbol[] ss_matches)
			: base(parent, rule, tfs, rgo, w, ss_matches)
		{
		}
		public override Tfs DerivationTfs()
		{
			return base.DerivationTfs();

			//TfsSlot ts_mrs = Tfs[mrsm.InitialSemanticsPath];
			//TfsSlot[] new_rels = mrsm.GetRelSlots(ts_mrs);

			//return StartSymbol != null && new_rels.Length == ctrl.input.Rels.Length &&
			//	ctrl.fsu.RelMatchHelper.CompareRels(ctrl.input.ts_mrs, ts_mrs, false, false);
		}
	};

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// 
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DebuggerDisplay("{ToString(),nq}")]
	public class gxo_nary_pack : GenControl._atfs_nary_pack, IChartObj<CoverageMap>
	{
		public gxo_nary_pack(IUnificationController parent, Rule rule, ArrayTfs tfs, IReadOnlyList<IChartObj> rgo, CoverageMap w, StartSymbol[] ss_matches)
			: base(parent, rule, tfs, rgo, w, ss_matches)
		{
		}
		public override Tfs DerivationTfs()
		{
			return base.DerivationTfs();

			//TfsSlot ts_mrs = Tfs[mrsm.InitialSemanticsPath];
			//TfsSlot[] new_rels = mrsm.GetRelSlots(ts_mrs);

			//return StartSymbol != null && new_rels.Length == ctrl.input.Rels.Length &&
			//	ctrl.fsu.RelMatchHelper.CompareRels(ctrl.input.ts_mrs, ts_mrs, false, false);
		}
	};
}
